package com.example.fw;

import java.util.HashSet;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.example.tests.ContactObject;

public class ContactHelper extends HelperWithWebDriverBase {

	private Contacts contactCash;

	public ContactHelper (ApplicationManager manager) {
		super(manager);
	}
	
	public Contacts getContacts() {
		if (contactCash == null) {
			buildContactCash();
		}
		return contactCash;
	}
	
	private void buildContactCash() {
		HashSet<ContactObject> set = new HashSet<ContactObject>();
		manager.getNavigationHelper().goToHomePage();
		WebElement table = findElements(By.tagName("table")).get(0);
		List<WebElement> checkboxes = table.findElements(By.name("entry"));
		for (WebElement checkbox : checkboxes) {
			String title = checkbox.getAttribute("title");
			Pattern p = Pattern.compile(".*\\((.*)\\)");
			Matcher m = p.matcher(title);
			if (m.matches()) {
				title = m.group(1);
			}			
			ContactObject contact = new ContactObject()
				.setFirstName(title)
				.setLastName(title)
				.setId(checkbox.getAttribute("value"));
			set.add(contact);
		}
		contactCash = new Contacts(set);
	}
	
	public void createContact(ContactObject contactObject) {
		initContactCreation();
		fillContactForm(contactObject, true);
		submitContactCreation();
		manager.getNavigationHelper().returnToHomePage();
		contactCash = null;
	}

	public void modifyContact(ContactObject contact, ContactObject contactObject) {
		markContact(contact);
		initContactModification();
		fillContactForm(contactObject, false);
		submitContactModification();
		manager.getNavigationHelper().returnToHomePage();
		contactCash = null;
	}

	public void deleteContact(ContactObject contact) {
		manager.getNavigationHelper().goToHomePage();
		markContact(contact);
		initContactModification();
		submitContactDelete();
		manager.getNavigationHelper().returnToHomePage();
		contactCash = null;
	}

	private void initContactCreation() {
		click(By.linkText("add new"));
	}

	private void initContactModification() {
		By initContactModificationButton = By.cssSelector("img[alt=\"Edit\"]");
		click(initContactModificationButton);
	}
	
	private void fillContactForm(ContactObject contactObject, boolean fillGroup) {
		type(By.name("firstname"), contactObject.firstName);
		type(By.name("lastname"), contactObject.lastName);
		type(By.name("address"), contactObject.mainAddress);
		type(By.name("home"), contactObject.telephoneHome);
		type(By.name("mobile"), contactObject.telephoneMobile);
		type(By.name("work"), contactObject.telephoneWork);
		type(By.name("email"), contactObject.mainEmail);
		type(By.name("email2"), contactObject.alternativeEmail);
		select(By.name("bday"), contactObject.birthDay);
		select(By.name("bmonth"), contactObject.birthMonth);
		type(By.name("byear"), contactObject.birthYear);
		if (fillGroup) {
			selectRandom(By.name("new_group"), contactObject.chooseGroup);
		} else {
			if (isGroupCheckBoxPresent(By.name("new_group"))) {
				throw new Error("Выпадающий список есть, а его не должно быть!");
			}
		}
		type(By.name("address2"), contactObject.alternativeAddress);
		type(By.name("phone2"), contactObject.alternativeTelephoneHome);
	}
	  
	private void submitContactCreation() {
		clickOnSubmitContactButton("submit");
	}
	
	private void markContact(ContactObject contact) {
		findElement(By.xpath("//input[@value='" + contact.id + "']")).click();		
	}

	private void submitContactModification() {		
		clickOnSubmitContactButton("update");
	}

	private void clickOnSubmitContactButton(String nameOfSubmitButton) {
		click(By.name(nameOfSubmitButton));
	}
	
	private void submitContactDelete() {
		By submitContactDeleteButton = By.xpath("(//input[@name='update'])[2]");
		click(submitContactDeleteButton);
	}
	  
	public boolean isGroupCheckBoxPresent(By locator) {
	    driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
	    boolean verdict = driver.findElements(locator).size() > 0;
	    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
	    return verdict;
	}
	
}
